The not-so-final word on final #JVMLS
Maurizio Cimadamore on August 12, 2025Developers have often heard the advice to “prefer immutability”. Immutability confers many advantages, since an immutable object can be only in one state and therefore can be shared freely with untrusted code and across multiple threads. Java’s main tool for managing immutability is final
fields. Unfortunately, using final
fields comes with limitations which restrict their use in many real-world applications.
While the compiler, and the putfield
bytecode protect against errant writes to final
fields, there are some gaps. For instance, final
fields can be reassigned more than once, either inside the constructor, or even outside (e.g. using setAccessible
). Because of this, final
fields can’t be trusted not to change (or to change only once), which undermines the integrity of Java applications, and precludes some important performance optimizations (such as constant-folding).
Moreover, initializaton of final
fields is rather inflexible: they must be set eagerly, either during construction (for instance fields) or during class initialization (for static fields) – and in the exact order in which they have been declared. Because of this, initializaton of final
fields cannot be shifted in time, so as to reduce the overall burden on application startup.
In this talk we will look at some of the steps we’re taking to address these limitations, and enable Java to take better advantage of immutable data.
Make sure to check the JVMLS 2025 playlist.